package ch.rheintalconnection.sysventory.businessServices;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import ch.rheintalconnection.sysventory.domain.Client;
import ch.rheintalconnection.sysventory.domain.Computer;
import ch.rheintalconnection.sysventory.domain.NIC;
import ch.rheintalconnection.sysventory.domain.OperatingSystem;
import ch.rheintalconnection.sysventory.domain.Printer;
import ch.rheintalconnection.sysventory.domain.Processor;
import ch.rheintalconnection.sysventory.domain.Program;
import ch.rheintalconnection.sysventory.domain.ScanEntry;
import ch.rheintalconnection.sysventory.dto.ComputerDto;
import ch.rheintalconnection.sysventory.dto.DtoContainer;
import ch.rheintalconnection.sysventory.dto.LogicalDiskDto;
import ch.rheintalconnection.sysventory.dto.NicDto;
import ch.rheintalconnection.sysventory.dto.OperatingSystemDto;
import ch.rheintalconnection.sysventory.dto.PrinterConfigurationDto;
import ch.rheintalconnection.sysventory.dto.PrinterDto;
import ch.rheintalconnection.sysventory.dto.ProcessorDto;
import ch.rheintalconnection.sysventory.dto.ProgramDto;
import ch.rheintalconnection.sysventory.foundation.ParseUtility;
import ch.rheintalconnection.sysventory.foundation.Time;
import ch.rheintalconnection.sysventory.technicalServices.IDataReader;

public class DtoToDomainConverter {
	
	IDataReader dataReader;
	
	
	
	public DtoToDomainConverter(IDataReader dataReader) {
		super();
		this.dataReader = dataReader;
	}

	public ScanEntry toScanEntry(DtoContainer dtos) throws UnknownHostException {
		
		Client client = toClient(dtos.getNicDto());
		
		Computer computer = toComputer(dtos.getComputerDto(), dtos.getLogicalDiskDto());
		NIC nic = toNic(dtos.getNicDto());
		OperatingSystem os = toOperatingSystem(dtos.getOperatingSystemDto());
		Processor processor = toProcessor(dtos.getProcessorDto());
		List<Printer> printers = toPrinters(dtos.getPrinterDtos(), dtos.getPrinterConfigurationDtos());
		List<Program> programs = toPrograms(dtos.getProgramDtos());
		
		return new ScanEntry(Time.now(), client, computer, nic, os, processor, printers, programs);
	}
	
private Client toClient(NicDto nicDto) {
	
		String macAddress = nicDto.getMacAddress().trim();
		
		// existing Client
		Client client =  dataReader.selectClient(macAddress);
		if (client == null) {
			
			// new Client
			client = new Client(macAddress);
		}
		
		return client;
	}

	public Computer toComputer(ComputerDto computerDto,
			LogicalDiskDto logicalDiskDto) {

		String computerName = computerDto.getComputerName();

		String sRam = computerDto.getRam();
		long ram = Long.parseLong(sRam);

		String computerType = computerDto.getComputerType();
		int iComputerType = ParseUtility.tryParseInt(computerType);
		computerType = convertIntToComputerType(iComputerType);

		String sHdCapacity = logicalDiskDto.getHdcapacity();
		long hdCapacity = ParseUtility.tryParseLong(sHdCapacity);

		String sFreespace = logicalDiskDto.getFreespace();
		long freespace = ParseUtility.tryParseLong(sFreespace);
		
		long hdOccupied = -1;
		if (hdCapacity >= 0 && freespace >= 0) {
			hdOccupied = hdCapacity - freespace;
		}
		Computer computer = new Computer(computerName, ram, computerType, hdCapacity, hdOccupied);
		return computer;
	}

	public NIC toNic(NicDto nicDto) throws UnknownHostException {
		
		NIC nic = null;
		
		String macAddress = nicDto.getMacAddress().trim();

		String sIpAddress = nicDto.getIpAddress().trim();
		sIpAddress = sIpAddress.split(" ")[0];
		InetAddress ipAddress;
		ipAddress = InetAddress.getByName(sIpAddress);
		

		String description = nicDto.getDescription();

		String sGateway = nicDto.getGateway().trim();
		sGateway = sGateway.split(" ")[0];
		InetAddress gateway = InetAddress.getByName(sGateway);

		String sDhcp = nicDto.getDhcp().trim();
		sDhcp = sDhcp.split(" ")[0];
		InetAddress dhcp;
		try {
			dhcp = InetAddress.getByName(sDhcp);
		}
		catch (UnknownHostException ex) {
			// No dhcp
			dhcp = null;
		}

		String sSubNet = nicDto.getSubNet().trim();
		sSubNet = sSubNet.split(" ")[0];
		InetAddress subNet = InetAddress.getByName(sSubNet);
		nic = new NIC(ipAddress, description, macAddress, gateway, dhcp,
				subNet);
		
		return nic;
	}

	public OperatingSystem toOperatingSystem(OperatingSystemDto operatingSystemDto) {
		
		String osDescription = operatingSystemDto.getDescription();
		String osVersion = operatingSystemDto.getVersion();
		String osTechnology = operatingSystemDto.getTechnology();
		
		OperatingSystem os = new OperatingSystem(osDescription, osVersion, osTechnology);
		return os;
	}

	public Processor toProcessor(ProcessorDto processorDto) {
		
		String processorDescription = processorDto.getDescription();
		String processorFamily = processorDto.getFamily();
		String sProcessorCores = processorDto.getCores();
		
		int processorCores = ParseUtility.tryParseInt(sProcessorCores);
		String processorClockrate = processorDto.getClockrate();
		
		Processor processor = new Processor(processorDescription, processorFamily, processorCores, processorClockrate);
		return processor;
	}

	public List<Printer> toPrinters(List<PrinterDto> printerDtos,
			List<PrinterConfigurationDto> printerConfigurationDtos) {

		List<Printer> printers = new ArrayList<Printer>();

		for (int i = 0; i < printerDtos.size(); i++) {

			PrinterDto printerDto = printerDtos.get(i);
			PrinterConfigurationDto printerConfigurationDto = printerConfigurationDtos
					.get(i);

			String description = printerDto.getDescription();
			String driver = printerDto.getDriver();
			String version = printerConfigurationDto.getVersion();

			printers.add(new Printer(description, driver, version));
		}
		return printers;
	}

	public List<Program> toPrograms(List<ProgramDto> programDtos) {

		List<Program> programs = new ArrayList<Program>();

		for (ProgramDto programDto : programDtos) {

			String description = programDto.getDescription();
			String version = programDto.getVersion();

			programs.add(new Program(description, version));
		}
		return programs;
	}
	
	private String convertIntToComputerType(int iType) {

		String computerType;

		switch (iType) {
		case 0:
			computerType = "Unspecified";
			break;
		case 1:
			computerType = "Desktop";
			break;
		case 2:
			computerType = "Mobile";
			break;
		case 3:
			computerType = "Workstation";
			break;
		case 4:
			computerType = "Enterprise Server";
			break;
		case 5:
			computerType = "mall Office and Home Office (SOHO) Server";
			break;
		case 6:
			computerType = "Appliance PC";
			break;
		case 7:
			computerType = "Performance Server";
			break;
		case 8:
			computerType = "Maximum";
			break;
		default:
			computerType = "Unspecified";
			break;
		}

		return computerType;
	}

}
